/**
 * @file server.h 服务端的头文件
 *  定义了服务端相关的函数和变量
 *  包括用户链表、互斥锁、线程ID等
 *  以及处理客户端请求的函数
 *  如注册、登录、显示用户、注销等
 * @author pzk (1528089905@qq.com)
 * @brief 
 * @version 1.5
 * @date 2025-8-25
 * 
 * @copyright copyright (c) 2025
 */
#ifndef SERVER_H
#define SERVER_H

#include "comm.h"
#include "dlist.h"

extern int user_id_min;       // 用户ID起始值
extern int user_count;        // 总用户数
extern pthread_mutex_t users_mutex,online_mutex;  // 互斥锁，用于保护用户数据
extern pthread_t pthid;       // 线程ID
extern int server_sock;       // 服务器套接字
extern node_t *users_list;    // 用户链表  
extern node_t *online_list;   // 在线用户链表  


/** 
 * @brief:  初始化服务器函数
 *          初始化用户链表和互斥锁
 *          创建TCP套接字,绑定地址,开始监听
 * @param:  无
 * @return: 无
 */
void init_server();

/** 
 * @brief:  加载用户数据函数
 *          加载用户数据到链表，不存在时初始化
 *          第一行为最小ID，第二行为用户数，第三行开始为用户数据
 * @param:  无
 * @return: 无
 */
void load_users_from_file();

/** 
 * @brief:  保存用户数据函数
 *          将用户数据保存到文件
 *          第一行为最小ID，第二行为用户数，第三行开始为用户数据
 * @param:  无
 * @return: 无
 */
void save_users_to_file(node_t *head);

/**
 * @brief: 处理请求函数
 * @param arg: 传入的参数
 * @return: 无
 */
void *handle_client(void *arg);

/** 
 * @brief:  注册请求处理函数
 *          解析客户端发送的注册信息，将新用户信息保存到用户链表中
 * @param client_fd: 客户端套接字描述符   
 * @param data: 客户端发送的注册信息
 * @return: 无
 */ 
void handle_register(int client_fd, const char *data);

/**
 * @brief: 用户登陆处理函数
 *          检查用户名和密码是否匹配，如果匹配则返回登陆成功，否则返回登陆失败
 * @param client_fd: 客户端文件描述符
 * @param data: 客户端发送的数据
 * @return: 无
 */
void handle_login(int client_fd, const char *data);

/**
 * @brief: 用户登出处理函数
 *         标记在线用户为离线状态（不删除节点）
 *         更新用户表状态，保存用户数据
 * @param client_fd: 客户端文件描述符
 * @param data: 客户端发送的数据
 * @return: 无
 */
void handle_logout(int client_fd, const char *data);

/**
 * @brief 显示用户处理函数
 *        解析指令数据，根据排序方式对用户列表进行排序，并发送排序后的用户列表给客户端
 * @param client_fd 客户端文件描述符
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_show_user(int client_fd, const char *data);

/**
 * @brief 用户查询处理函数
 * @param client_fd 客户端文件描述符
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_find(int client_fd, const char *data);

/**
 * @brief 用户删除处理函数
 *        根据用户提供的ID、姓名或电话号码删除用户
 * @param client_fd 客户端文件描述符
 * @param data 删除指令数据
 * 
 * @return 无
 */
void handle_delete(int client_fd, const char *data);

/**
 * @brief 获取在线列表处理函数
 *        获取在线用户列表并发送给客户端
 * @param client_fd 客户端文件描述符
 * 
 * @return 无
 */
void handle_get_online(int client_fd);

/**
 * @brief 私聊请求处理函数
 *        查找目标用户是否在线，如果在线则向目标用户发送私聊请求
 * @param client_fd 客户端套接字
 * @param data 指令数据
 *
 * @return 无
 */
void handle_private_request(int client_fd, const char *data);

/**
 * @brief 私聊接受处理函数
 *        根据指令格式解析出接受方ID和发起方ID，然后查找发起方用户，并发送接受通知
 * @param client_fd 客户端套接字
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_private_accept(int client_fd, const char *data);

/**
 * @brief 私聊拒绝处理函数
 *        根据指令格式解析出接受方ID和发起方ID，然后查找发起方用户，并发送拒绝通知
 * @param client_fd 客户端套接字
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_private_refuse(int client_fd, const char *data);

/**
 * @brief 私聊消息处理函数
 *        根据指令格式解析发送方ID、接收方ID和消息内容，查找目标用户并发送消息        
 * @param client_fd 客户端套接字
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_private_msg(int client_fd, const char *data);

/**
 * @brief 私聊退出处理函数
 * @param client_fd 客户端套接字
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_private_exit(int client_fd, const char *data);

/**
 * @brief 私聊查看信息处理函数
 * @param client_fd 客户端套接字
 * @param data 指令数据
 * 
 * @return 无
 */
void handle_user_info(int client_fd, const char *data);


/**
 * @brief：查找用户辅助函数
 *         根据比较函数查找用户
 * @param head: node_t*用户链表头
 * @param cmpfun: cmpfun_t比较函数
 * @param user: const users_t*用户
 * 
 * @return: node_t*找到的用户节点链表
 */
node_t *find_user(node_t *head, cmpfun_t cmpfun, const users_t *user);

/**
 * @brief 排序辅助函数
 * @param head 链表头节点
 * @param cmpfun 比较函数指针
 * 
 * @return int 0成功 -1失败
 */
int sort_user(node_t *head, cmpfun_t cmpfun);

/**
 * @brief 删除辅助函数
 * @param head 链表头节点
 * @param dev 要删除的节点数据
 * @param cmpfun 比较函数
 * 
 * @return 0: 成功删除，-1: 未找到要删除的节点
 */
int del_user(node_t *head, cmpfun_t cmpfun, const users_t *dev);

/** 
 * @brief:  比较辅助函数
 *          根据用户名，用户ID，电话号码比较
 *          用于删除，查找，排序
 * @param data1: 指向第一个用户结构体的指针
 * @param data2: 指向第二个用户结构体的指针
 * @return: 返回比较结果
 */
int cmpUser_Name(const void *data1,const void *data2);
int cmpUser_ID(const void *data1, const void *data2);
int cmpUser_Phone(const void *data1, const void *data2);



#endif